package com.zhongkun.datahome.service.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zhongkun.datahome.common.exception.ServiceException;
import com.zhongkun.datahome.service.constant.FileTypeEnum;
import com.zhongkun.datahome.service.constant.SwitchEnum;
import com.zhongkun.datahome.service.constant.YesOrNoEnum;
import com.zhongkun.datahome.service.domain.CommonFile;
import com.zhongkun.datahome.service.domain.DecorationStandardItem;
import com.zhongkun.datahome.service.domain.HouseMaterial;
import com.zhongkun.datahome.service.domain.Sku;
import com.zhongkun.datahome.service.mapper.SkuMapper;
import com.zhongkun.datahome.service.processor.SkuDataProcessor;
import com.zhongkun.datahome.service.processor.dto.SkuDto;
import com.zhongkun.datahome.service.repository.*;
import com.zhongkun.datahome.service.req.cmd.sku.SkuCmd;
import com.zhongkun.datahome.service.req.cmd.sku.SwitchSkuCmd;
import com.zhongkun.datahome.service.req.qry.sku.SkuExistQry;
import com.zhongkun.datahome.service.req.qry.sku.SkuQry;
import com.zhongkun.datahome.service.res.CommonFileVo;
import com.zhongkun.datahome.service.res.PageVo;
import com.zhongkun.datahome.service.res.sku.SkuVo;
import com.zhongkun.datahome.service.service.IFileService;
import com.zhongkun.datahome.service.service.ISkuService;
import com.zhongkun.datahome.service.utils.ExcelUtil;
import com.zhongkun.datahome.service.utils.StreamUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 商品信息Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-04-14
 */
@Service
public class SkuServiceImpl implements ISkuService {
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Resource
    private SkuMapper skuMapper;

    @Resource
    private SkuRepository skuRepository;

    @Resource
    private CommonFileRepository commonFileRepository;

    @Resource
    private IFileService fileService;

    @Resource
    private HouseMaterialRepository houseMaterialRepository;

    @Resource
    private DecorationStandardItemRepository decorationStandardItemRepository;

    @Resource
    private DecorationStandardRepository decorationStandardRepository;

    @Resource
    private CustomerHouseRepository customerHouseRepository;

    /**
     * 查询商品信息
     * 
     * @param id 商品信息主键
     * @return 商品信息
     */
    @Override
    public SkuVo selectSkuById(Long id) {
        Sku sku = skuMapper.selectSkuById(id);
        if (Objects.isNull(sku)) {
            return null;
        }

        List<CommonFile> commonFiles = commonFileRepository.listBySkuId(id.toString(), FileTypeEnum.COMMON_PIC.getType());
        List<CommonFileVo> commonFileVos = commonFiles.stream()
                .sorted(Comparator.comparing(CommonFile::getSort))
                .map(CommonFileVo::convert)
                .collect(Collectors.toList());

        return SkuVo.convert(sku, commonFileVos);
    }

    /**
     * 查询商品信息列表
     * 
     * @param qry 商品信息
     * @return 商品信息
     */
    @Override
    public PageVo<SkuVo> pageSku(SkuQry qry) {
        IPage<Sku> pageResult = skuRepository.pageSku(qry);
        if (CollectionUtils.isEmpty(pageResult.getRecords())) {
            return PageVo.emptyPage(qry.getPageNo(), qry.getPageSize());
        }

        List<SkuVo> skuVoList = pageResult.getRecords().stream()
                .map(SkuVo::convert)
                .collect(Collectors.toList());

        // 头图
        List<String> skuIds = skuVoList.stream()
                .map(item -> String.valueOf(item.getId()))
                .collect(Collectors.toList());

        Map<String, CommonFile> headPicsMap = commonFileRepository.getSkuHeadPicsMap(skuIds, FileTypeEnum.COMMON_PIC.getType());
        skuVoList.forEach(skuVo -> {
            if (headPicsMap.containsKey(String.valueOf(skuVo.getId()))) {
                skuVo.setHeadPicUrl(headPicsMap.get(String.valueOf(skuVo.getId())).getFileUrl());
            }
        });

        return new PageVo<>(skuVoList, qry.getPageNo(), qry.getPageSize(), pageResult.getTotal());
    }

    @Override
    @Transactional
    public Long addSku(SkuCmd cmd) {
        // 重复校验
        Map<String, Long> skuExistMap = querySkuExist(Collections.singletonList(SkuExistQry.of(cmd)));
        if (!skuExistMap.isEmpty() && skuExistMap.containsKey(cmd.getKey())) {
            throw new ServiceException("商品信息已存在");
        }

        cmd.setSource("back_add");
        return this.insertSku(cmd);
    }

    /**
     * 新增商品信息
     * 
     * @param cmd 商品信息
     * @return 结果
     */
    @Override
    public Long insertSku(SkuCmd cmd) {
        Sku sku = Sku.convert(cmd);
        skuRepository.save(sku);
        // 保存图片
        saveSkuCommonPic(sku.getId(), cmd.getPictureUrls());
        return sku.getId();
    }

    private void saveSkuCommonPic(Long skuId, List<String> pictureUrls) {
        if (CollectionUtils.isEmpty(pictureUrls)) {
            return;
        }

        commonFileRepository.saveBatch(toSkuCommonPic(skuId, pictureUrls));
    }

    private List<CommonFile> toSkuCommonPic(Long skuId, List<String> pictureUrls) {

        List<CommonFile> fileList = new ArrayList<>();
        int sort = 0;
        for (String url : pictureUrls) {
            CommonFile commonFile = CommonFile.convertSkuCommonPic(skuId, url, sort++);
            commonFile.setFileSize(fileService.getFileSize(url));
            fileList.add(commonFile);
        }
        // 第一张设为头图
        fileList.get(0).setIsHead(YesOrNoEnum.YES.getCode());
        return fileList;
    }

    /**
     * 修改商品信息
     * 
     * @param cmd 商品信息
     * @return 结果
     */
    @Override
    @Transactional
    public boolean updateSku(SkuCmd cmd) {
        Sku sku = skuMapper.selectSkuById(cmd.getId());
        if (Objects.isNull(sku)) {
            throw new ServiceException("商品不存在，skuId=" + cmd.getId());
        }

        // 重复校验
        if (sku.getKeyChangeFlag(cmd)) {
            Map<String, Long> skuExistMap = querySkuExist(Collections.singletonList(SkuExistQry.of(cmd)));
            if (!skuExistMap.isEmpty() && skuExistMap.containsKey(cmd.getKey())) {
                throw new ServiceException("商品信息已存在");
            }
        }

        sku.update(cmd);
        skuRepository.updateById(sku);

        // 保存图片
        commonFileRepository.removeBySkuId(Collections.singletonList(sku.getId().toString()), FileTypeEnum.COMMON_PIC.getType());
        saveSkuCommonPic(sku.getId(), cmd.getPictureUrls());
        return true;
    }

    @Override
    public void switchByIds(SwitchSkuCmd cmd) {
        if (CollectionUtils.isEmpty(cmd.getIds())) {
            return;
        }

        if (!SwitchEnum.isValid(cmd.getStatus())) {
            throw new ServiceException("商品上/下架状态无效");
        }

        List<Sku> skus = skuRepository.listByIds(cmd.getIds());

        if (CollectionUtils.isNotEmpty(skus)) {
            skus.forEach(sku -> sku.setStatus(cmd.getStatus()));
            skuRepository.updateBatchById(skus);
        }
    }

    /**
     * 批量删除商品信息
     * 
     * @param ids 需要删除的商品信息主键
     * @return 结果
     */
    @Override
    @Transactional
    public boolean deleteSkuByIds(List<Long> ids) {
        if (CollectionUtils.isNotEmpty(ids)) {
            // 校验是否被装标/房产引用
            ids.forEach(skuId -> {
                List<DecorationStandardItem> items = decorationStandardItemRepository.listBySkuId(skuId);
                Set<String> atStandardNames = decorationStandardRepository.getStandardNames(items.stream()
                        .map(DecorationStandardItem::getStandardId)
                        .collect(Collectors.toList()));
                if (CollectionUtils.isNotEmpty(atStandardNames)) {
                    throw new ServiceException("商品ID【" + skuId + "】已被装标【" + String.join(",", atStandardNames) + "】引用，不能删除");
                }

                List<HouseMaterial> houseMaterials = houseMaterialRepository.listBySkuId(skuId);
                Set<String> houseKeyNames = customerHouseRepository.getHouseKeyNames(houseMaterials.stream()
                        .map(HouseMaterial::getHouseId)
                        .collect(Collectors.toList()));
                if (CollectionUtils.isNotEmpty(houseKeyNames)) {
                    throw new ServiceException("商品ID【" + skuId + "】已被房产【" + String.join(",", houseKeyNames) + "】引用，不能删除");
                }
            });

            skuRepository.removeBatchByIds(ids);

            // 删除图片
            List<String> skuIds = ids.stream().map(String::valueOf).collect(Collectors.toList());
            commonFileRepository.removeBySkuId(skuIds, FileTypeEnum.COMMON_PIC.getType());
        }
        return true;
    }

    @Override
    public Map<String, Long> querySkuExist(List<SkuExistQry> skuExistQryList) {
        if (CollectionUtils.isEmpty(skuExistQryList)) {
            return Collections.emptyMap();
        }

        List<Sku> skuList = skuRepository.getBaseMapper().querySkuExist(skuExistQryList);
        return StreamUtil.listToMap(skuList, Sku::getKey, Sku::getId);
    }

//    @Override
//    public Map<String, Long> querySkuExist(List<SkuExistQry> skuExistQryList) {
//        if (CollectionUtils.isEmpty(skuExistQryList)) {
//            return Collections.emptyMap();
//        }
//
//        LambdaQueryWrapper<Sku> wrapper = new LambdaQueryWrapper<Sku>();
//        wrapper.and(w -> {
//            for (SkuExistQry qry : skuExistQryList) {
//                w.or(w1 -> w1.and(w2 -> {
//                            if (qry.getSkuName() != null) {
//                                w2.eq(Sku::getSkuName, qry.getSkuName());
//                            } else {
//                                w2.isNull(Sku::getSkuName);
//                            }
//                        })
//                        .and(w2 -> {
//                            if (qry.getCategory() != null) {
//                                w2.eq(Sku::getCategory, qry.getCategory());
//                            } else {
//                                w2.isNull(Sku::getCategory);
//                            }
//                        })
//                        .and(w2 -> {
//                            if (qry.getUnit() != null) {
//                                w2.eq(Sku::getUnit, qry.getUnit());
//                            } else {
//                                w2.isNull(Sku::getUnit);
//                            }
//                        })
//                        .and(w2 -> {
//                            if (qry.getBrandName() != null) {
//                                w2.eq(Sku::getBrandName, qry.getBrandName());
//                            } else {
//                                w2.isNull(Sku::getBrandName);
//                            }
//                        })
//                        .and(w2 -> {
//                            if (qry.getSpecification() != null) {
//                                w2.eq(Sku::getSpecification, qry.getSpecification());
//                            } else {
//                                w2.isNull(Sku::getSpecification);
//                            }
//                        })
//
//                );
//            }
//        });
//
//        return StreamUtil.listToMap(skuMapper.selectList(wrapper), Sku::getKey, Sku::getId);
//    }



    @Override
    @Transactional
    public void upload(MultipartFile file) {
        try {
            // 解析行数据
            SkuDataProcessor dataProcessor = new SkuDataProcessor();
            EasyExcel.read(file.getInputStream(), SkuDto.class, dataProcessor).sheet().doRead();
            List<SkuDto> dataList = dataProcessor.getCachedDataList();

            // 解析并上传图片
            Map<Integer, List<String>> imageUrlsMap = ExcelUtil.uploadImageData(file);

            // 重复数据过滤
            Map<String, Long> existSkuMap = this.querySkuExist(dataList.stream()
                    .map(SkuExistQry::of)
                    .collect(Collectors.toList()));

            Map<String, Sku> toSaveSkuMap = dataList.stream()
                    .map(Sku::convert)
                    .filter(item -> !existSkuMap.containsKey(item.getKey()))
                    .collect(Collectors.toMap(Sku::getKey, v -> v, (v1, v2) -> v1));

            Map<String, List<String>> skuPicUrlsMap = dataList.stream()
                    .peek(item -> item.setUrls(imageUrlsMap.getOrDefault(item.getRowIndex(), Collections.emptyList())))
                    .collect(Collectors.toMap(SkuDto::getKey, SkuDto::getUrls, (v1, v2) -> CollectionUtils.isNotEmpty(v1) ? v1 : v2));

            List<CommonFile> toSaveSkuPicList = new ArrayList<>();

            if (CollectionUtils.isNotEmpty(toSaveSkuMap.values())) {
                skuRepository.saveBatch(toSaveSkuMap.values());
                // 保存图片
                toSaveSkuMap.values().forEach(sku -> {
                    if (CollectionUtils.isNotEmpty(skuPicUrlsMap.get(sku.getKey()))) {
                        toSaveSkuPicList.addAll(this.toSkuCommonPic(sku.getId(), skuPicUrlsMap.get(sku.getKey())));
                    }
                });

                if (CollectionUtils.isNotEmpty(toSaveSkuPicList)) {
                    commonFileRepository.saveBatch(toSaveSkuPicList);
                }
            }
            log.info("上传商品，新增{}条", toSaveSkuMap.size());
        } catch (IOException e) {
            log.error("上传商品，excel文件读取失败", e);
            throw new RuntimeException(e);
        }
    }
}
